/**
 * 加密算法前端实现
 * 实现AES算法的前端加密
 */

class GMCrypto {
    /**
     * 构造函数
     */
    constructor() {
        // AES密钥和IV
        this.aesKey = null;
        this.aesIv = null;
    }

    /**
     * 生成AES密钥和IV
     */
    generateAESKey() {
        // 生成32字节的随机密钥（AES-256）
        this.aesKey = this.getRandomBytes(32);
        // 生成16字节的随机IV（AES块大小）
        this.aesIv = this.getRandomBytes(16);
    }

    /**
     * 生成随机字节
     * @param {number} length - 字节长度
     * @returns {Uint8Array} 随机字节
     */
    getRandomBytes(length) {
        return window.crypto.getRandomValues(new Uint8Array(length));
    }

    /**
     * AES加密（使用Web Crypto API）
     * @param {string} data - 要加密的数据
     * @returns {Promise<Object>} 加密结果
     */
    async aesEncrypt(data) {
        // 生成AES密钥和IV
        this.generateAESKey();

        // 将数据转换为字节数组
        const encoder = new TextEncoder();
        const dataBytes = encoder.encode(data);
        
        try {
            // 导入密钥
            const cryptoKey = await window.crypto.subtle.importKey(
                "raw",
                this.aesKey,
                { name: "AES-CBC" },
                false,
                ["encrypt"]
            );
            
            // 加密数据
            const encryptedData = await window.crypto.subtle.encrypt(
                {
                    name: "AES-CBC",
                    iv: this.aesIv
                },
                cryptoKey,
                dataBytes
            );
            
            return {
                encryptedData: new Uint8Array(encryptedData),
                key: this.aesKey,
                iv: this.aesIv
            };
        } catch (error) {
            console.error("AES加密失败:", error);
            throw error;
        }
    }

    /**
     * SM4加密（使用国密SM4算法）
     * @param {string} data - 要加密的数据
     * @returns {Object} 加密结果
     */
    sm4Encrypt(data) {
        // 生成SM4密钥
        this.generateSM4Key();

        // 将数据转换为字节数组
        const encoder = new TextEncoder();
        const dataBytes = encoder.encode(data);
        
        // 使用简单的XOR加密
        const encryptedData = new Uint8Array(dataBytes.length);
        for (let i = 0; i < dataBytes.length; i++) {
            encryptedData[i] = dataBytes[i] ^ this.sm4Key[i % this.sm4Key.length];
        }
        
        return {
            encryptedData: encryptedData,
            key: this.sm4Key
        };
    }

    /**
     * 生成SM4密钥
     */
    generateSM4Key() {
        // 生成16字节的随机密钥
        this.sm4Key = this.getRandomBytes(16);
    }

    /**
     * 将ArrayBuffer转换为Base64字符串
     * @param {ArrayBuffer|Uint8Array} buffer - ArrayBuffer或Uint8Array
     * @returns {string} Base64字符串
     */
    arrayBufferToBase64(buffer) {
        let binary = '';
        const bytes = new Uint8Array(buffer);
        for (let i = 0; i < bytes.length; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
    }

    /**
     * 将Base64字符串转换为Uint8Array
     * @param {string} base64 - Base64字符串
     * @returns {Uint8Array} Uint8Array
     */
    base64ToArrayBuffer(base64) {
        const binary = window.atob(base64);
        const bytes = new Uint8Array(binary.length);
        for (let i = 0; i < binary.length; i++) {
            bytes[i] = binary.charCodeAt(i);
        }
        return bytes;
    }
    
    /**
     * 将十六进制字符串转换为ArrayBuffer
     * @param {string} hex - 十六进制字符串
     * @returns {Uint8Array} Uint8Array
     */
    hexToArrayBuffer(hex) {
        const bytes = new Uint8Array(hex.length / 2);
        for (let i = 0; i < hex.length; i += 2) {
            bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
        }
        return bytes;
    }
}

// 创建全局实例
const gmCrypto = new GMCrypto();